<template>
  <div class="role-container-padding">
    <vxe-grid
      ref="xGrid"
      border
      stripe
      keep-source
      auto-resize
      sync-resize
      :height="height"
      :loading="listLoading"
      :column-config="{ resizable: true }"
      :export-config="{}"
      :columns="tableColumn"
      align="center"
      :row-config="{ keyField: 'id', isCurrent: true, isHover: true }"
      :seq-config="{ seqMethod: seqMethod }"
    >
      <template #form>
        <vxe-form
          ref="queryParamsRef"
          title-align="right"
          title-width="120"
          prevent-submit
        >
          <vxe-form-item title="表名称" span="8">
            <template #default>
              <el-input
                v-model="queryParams.tableName"
                class="!w-240px"
                clearable
                placeholder="请输入表名称"
                @keyup.enter="queryData"
              />
            </template>
          </vxe-form-item>
          <vxe-form-item title="表描述" span="8">
            <template #default>
              <el-input
                v-model="queryParams.tableComment"
                class="!w-240px"
                clearable
                placeholder="请输入表描述"
                @keyup.enter="queryData"
              />
            </template>
          </vxe-form-item>
          <vxe-form-item title="表描述" span="8">
            <template #default>
              <el-date-picker
                v-model="queryParams.createTime"
                :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
                class="!w-240px"
                end-placeholder="结束日期"
                start-placeholder="开始日期"
                type="daterange"
                value-format="YYYY-MM-DD HH:mm:ss"
              />
            </template>
          </vxe-form-item>
          <vxe-form-item span="24" align="center">
            <el-button
              v-permissions="{ permission: ['system:role:query'] }"
              :icon="Search"
              plain
              @click="queryData"
            >
              查询
            </el-button>
            <el-button
              v-permissions="{ permission: ['infra:codegen:create'] }"
              type="primary"
              plain
              @click="openImportTable()"
            >
              <i class="icon-wpkj-add-select"></i>
              导入
            </el-button>
          </vxe-form-item>
        </vxe-form>
      </template>
      <template #bottom>
        <el-pagination
          background
          :current-page="queryParams.pageNo"
          :layout="layout"
          :page-size="queryParams.pageSize"
          :total="total"
          @current-change="handleCurrentChange"
          @size-change="handleSizeChange"
        />
      </template>
      <template #status="{ row }">
        <el-switch
          v-model="row.status"
          active-color="#13ce66"
          inactive-color="#ff4949"
          :active-value="0"
          :inactive-value="1"
          @change="changeRoleStatus(row)"
        />
      </template>
      <template #dataSource="{ row }">
        <div>
          {{
            dataSourceConfigList.find(
              (config) => config.id === row.dataSourceConfigId
            )?.name
          }}
        </div>
      </template>
      <template #operate="{ row }">
        <div>
          <el-button
            v-permissions="{ permission: ['infra:codegen:preview'] }"
            type="primary"
            size="small"
            plain
            :icon="Edit"
            @click="handlePreview(row)"
          >
            预览
          </el-button>
          <el-button
            v-permissions="{
              permission: ['infra:codegen:update'],
            }"
            type="primary"
            size="small"
            plain
            @click="handleUpdate(row)"
          >
            编辑
          </el-button>
          <el-button
            v-permissions="{ permission: ['infra:codegen:delete'] }"
            size="small"
            type="danger"
            plain
            @click="handleDelete(row)"
          >
            删除
          </el-button>
          <el-button
            v-permissions="{ permission: ['infra:codegen:update'] }"
            link
            type="primary"
            @click="handleSyncDB(scope.row)"
          >
            同步
          </el-button>
          <el-button
            v-permissions="{ permission: ['infra:codegen:download'] }"
            link
            type="primary"
            @click="handleGenTable(scope.row)"
          >
            生成代码
          </el-button>
        </div>
      </template>
    </vxe-grid>
    <PreviewCode ref="previewCodeRef" @fetch-data="fetchData" />
    <EditTable ref="editTableRef" @fetch-data="fetchData" />
    <ImportTable ref="importTableRef" @fetch-data="fetchData" />
  </div>
</template>

<script>
  import * as CodegenApi from '@/api/infra/codegen'
  import * as DataSourceConfigApi from '@/api/infra/dataSourceConfig'
  import download from '@/utils/download'
  import { Delete, Edit, Plus, Search } from '@element-plus/icons-vue'

  export default defineComponent({
    name: 'InfraCodegen',
    components: {
      PreviewCode: defineAsyncComponent(() =>
        import('./components/PreviewCode')
      ),
      EditTable: defineAsyncComponent(() => import('./components/EditTable')),
      ImportTable: defineAsyncComponent(() =>
        import('./components/ImportTable')
      ),
    },
    setup() {
      const $baseConfirm = inject('$baseConfirm')
      const $baseMessage = inject('$baseMessage')
      const $baseTableHeight = inject('$baseTableHeight')
      const { push } = useRouter() // 路由跳转
      const state = reactive({
        height: $baseTableHeight(0),
        xGrid: null,
        previewCodeRef: null,
        editTableRef: null,
        importTableRef: null,
        dataSourceConfigList: [],
        tableColumn: [
          { type: 'seq', title: '序号', width: 50, fixed: 'left' },
          {
            title: '数据源',
            field: 'name',
            width: 160,
            slots: { default: 'dataSource' },
          },
          {
            title: '表名称',
            field: 'tableName',
            width: 160,
          },
          {
            title: '表描述',
            field: 'tableComment',
            width: 300,
          },
          {
            title: '实体',
            width: 120,
            field: 'className',
          },
          {
            title: '创建时间',
            field: 'createTime',
            width: 120,
            formatter: ['formatDate', 'yyyy-MM-dd HH:mm:ss'],
          },
          {
            title: '更新时间',
            width: 120,
            field: 'updateTime',
            formatter: ['formatDate', 'yyyy-MM-dd HH:mm:ss'],
          },
          {
            title: '操作',
            minWidth: 320,
            fixed: 'right',
            slots: { default: 'operate' },
          },
        ],
        listLoading: false,
        layout: 'total, sizes, prev, pager, next, jumper',
        total: 0,
        selectRows: '',
        queryParams: {
          pageNo: 1,
          pageSize: 30,
          tableName: undefined,
          tableComment: undefined,
          createTime: [],
        },
      })

      const setSelectRows = (val) => {
        state.selectRows = val
      }

      /** 导入操作 */
      const openImportTable = () => {
        state['importTableRef'].open()
      }

      const handleUpdate = (row) => {
        if (row.id) {
          push(`/codegen/edit?id=${id}`)
        } else {
          state['editRef'].showEdit()
        }
      }

      /** 预览操作 */
      const handlePreview = (row) => {
        state['previewRef'].open(row.id)
      }

      /** 同步操作  */
      const handleSyncDB = async (row) => {
        // 基于 DB 同步
        const tableName = row.tableName
        $baseConfirm(`确认要强制同步${tableName}表结构吗?`, null, async () => {
          await CodegenApi.syncCodegenFromDB(row.id)
          message.success('同步成功')
        })
      }

      /** 生成代码操作 */
      const handleGenTable = async (row) => {
        const res = await CodegenApi.downloadCodegen(row.id)
        download.zip(res, `codegen-${row.className}.zip`)
      }

      const handleDelete = (row) => {
        if (row) {
          $baseConfirm('你确定要删除当前项吗', null, async () => {
            const { msg } = await CodegenApi.deleteCodegenTable(row.id).catch(
              (err) => {
                state.listLoading = false
              }
            )
            $baseMessage(msg, 'success', 'vab-hey-message-success')
            await fetchData()
          })
        } else {
          $baseMessage('未选中任何行', 'error', 'vab-hey-message-error')
        }
      }

      const handleSizeChange = (val) => {
        state.queryParams.pageSize = val
        fetchData()
      }

      const handleCurrentChange = (val) => {
        state.queryParams.pageNo = val
        fetchData()
      }

      const queryData = () => {
        state.queryParams.pageNo = 1
        fetchData()
      }

      const fetchData = async () => {
        state.listLoading = true
        const { code, data, msg } = await CodegenApi.getCodegenTablePage(
          state.queryParams
        ).catch((err) => {
          state.listLoading = false
        })
        if (code == 0 || code == 200) {
          state['xGrid'].reloadData(data.list)
          state.total = data.total
          state.listLoading = false
        } else {
          state.listLoading = false
        }
      }

      const seqMethod = ({ row, rowIndex, column, columnIndex }) => {
        return (
          (state.queryParams.pageNo - 1) * state.queryParams.pageSize +
          rowIndex +
          1
        )
      }

      onMounted(async () => {
        await fetchData()
        // 加载数据源列表
        const { code, data, msg } =
          await DataSourceConfigApi.getDataSourceConfigList()
        state.dataSourceConfigList = data
      })

      onBeforeMount(() => {
        window.addEventListener('resize', handleHeight)
      })

      onBeforeUnmount(() => {
        window.removeEventListener('resize', handleHeight)
      })

      const handleHeight = () => {
        state.height = $baseTableHeight(0)
      }

      return {
        ...toRefs(state),
        setSelectRows,
        handleUpdate,
        handleDelete,
        handleSizeChange,
        handleCurrentChange,
        queryData,
        fetchData,
        Edit,
        Delete,
        Plus,
        Search,
        seqMethod,
        openImportTable,
        handleGenTable,
        handleSyncDB,
        handlePreview,
      }
    },
  })
</script>
